
//将本地服务发布为rpc服务的样例代码
//这些是业务代码，不是框架代码
#include<iostream>
#include<string>
// #include"user.pb.h"


#include"user.pb.h"
#include"mprpcapplication.h"
#include"rpcprovider.h"
#include"logger.h"

using namespace std;

/*
UserService原来是一个本地服务，提供了两个进程内的本地方法，Login和GetFriendLists

*/
class UserService : public fixbug::UserServiceRpc //使用在rpc服务发布端 （rpc服务提供者）
{
public:
    bool Login(std::string name,std::string pwd){
        std::cout<<"doing local service: login"<<std::endl;
        std::cout<<"name: "<<name<<" pwd: "<<pwd<<std::endl;
        return true;
        
    }
    //重写基类UserServiceRpc的虚函数 下面的这些方法按道理都是框架直接调用的
    /*
    1.caller给框架发出请求，框架执行===>Login(LoginRequest) ===>muduo===>calee
    2.callee(服务端框架收到)===>Login(LoginRequest)==>框架调用下面这个重写的方法
    */
   //框架调用这个方法，下面这个方法是个业务代码
   void Login(::google::protobuf::RpcController* controller,
                       const ::fixbug::LoginRequest* request,
                       ::fixbug::LoginResponse* response,
                       ::google::protobuf::Closure* done)
    {

        //1.取出请求数据

        std::string name = request->name();
        std::string pwd = request->pwd();

        //2.调用本地服务方法
        bool login_result =  Login(name,pwd);

        //3.把响应写入
        fixbug::ResultCode* code =  response->mutable_result();
        code->set_errcode(0);
        code->set_errmsg("");
        response->set_sucess(login_result);
    

        //回送信息，done里面的run是纯虚函数，完全重定义，（序列化，muduo库发送,都是由框架来完成）

        done->Run();

    
    
    }


};

//生成了一个provider可执行文件，我们想用户调用的时候直接写provider -i config.conf
//目标：想把上述服务发表为rpc服务,UserServiceRpc提供了一个Login虚函数，重写它
 int main(int argc,char** argv){ 
    //  LOG_INFO("this is a test message!");
    //  LOG_ERR("%s %s %d",__FILE__,__FUNCTION__,__LINE__); 

     //1.要使用这个框架，先调用框架的初始化操作    
    MprpcApplication::Init(argc,argv);

    //2.框架提供发布服务，provider是一个rpc网络服务对象，将UserService对象发布到rpc节点上
    /*
        通俗一点的讲法就是，客户端发布rpc方法请求，框架接收后，怎么定位到本地方法执行（怎么定位到本地UserService 的Login方法） 
    */
    RpcProvider provider;
    provider.NotifyService(new UserService());

    //3.启动一个rpc服务发布节点，Run以后 ，阻塞，等待远程rpc的调用请求
    provider.Run();

    return 0;
 }
